package blocksim.hash;

import java.nio.ByteBuffer;
import java.security.NoSuchAlgorithmException;

/**
 * Abstract class for hash strategies that applies the function in a window,
 * i.e. the hash function is applied only for the last "windowSize" added bytes
 * 
 * @author marcus
 */
public abstract class AbstractBufferedHashStrategy implements HashStrategy {

  protected ByteBuffer data;
  protected int windowSize;

  public AbstractBufferedHashStrategy(int windowSize) throws NoSuchAlgorithmException {
    this.windowSize = windowSize;
    this.data = ByteBuffer.allocate(windowSize);
  }

  @Override
  public void pushBytes(byte[] bytes) {
    pushBytes(bytes, 0, bytes.length);
  }

  @Override
  public void pushBytes(byte[] bytes, int offset, int len) {
    int diff = windowSize - len;
    int newPos = Math.max(0, diff);
    if (len < windowSize) {
      data.rewind();
      data.put(data.array(), len, diff);
    }
    data.position(newPos);
    data.put(bytes, Math.max(offset, len - windowSize), Math.min(windowSize, len));
  }

  public abstract byte[] hash();
}
